package com.xqboss.apps.service.synthesis;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.xqboss.apps.domain.synthesis.Synthesis;
import com.xqboss.apps.domain.synthesis.SynthesisRecordConsumeResult;
import com.xqboss.apps.domain.synthesis.SynthesisUserRecord;
import com.xqboss.apps.dto.synthesis.SynthesisStartDto;
import com.xqboss.apps.dto.synthesis.SynthesisUserRecordPageDto;
import com.xqboss.apps.enums.synthesis.SynthesisActivityTypeEnum;
import com.xqboss.apps.enums.synthesis.SynthesisRecordTypeEnum;
import com.xqboss.apps.mapper.synthesis.SynthesisRecordConsumeResultMapper;
import com.xqboss.apps.mapper.synthesis.SynthesisUserRecordMapper;
import com.xqboss.apps.vo.synthesis.SynthesisUserRecordVo;
import com.xqboss.chain.domain.chain.dto.BaseRequest;
import com.xqboss.common.exception.ServiceException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 合成用户记录 服务实现类
 * </p>
 *
 * @author 木鱼
 * @since 2023-11-29
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class SynthesisUserRecordService extends ServiceImpl<SynthesisUserRecordMapper, SynthesisUserRecord> {

    private final SynthesisRecordConsumeResultMapper synthesisRecordConsumeResultMapper;

    public List<SynthesisUserRecord> selectBasicList(BaseRequest request) {
        return baseMapper.selectList(Wrappers.<SynthesisUserRecord>lambdaQuery());
    }

    public SynthesisUserRecord selectByIdBasic(Long id) {
        return baseMapper.selectById(id);
    }

    public boolean saveBasic(SynthesisUserRecord record) {
        return baseMapper.insert(record) > 0;
    }

    public boolean updateBasic(SynthesisUserRecord record) {
        return baseMapper.updateById(record) > 0;
    }

    public boolean removeBasic(Long id) {
        return baseMapper.deleteById(id) > 0;
    }

    public List<SynthesisUserRecordVo> userSynthesisList(SynthesisUserRecordPageDto pageDto, Long userId) {
        pageDto.setUserId(userId);
        pageDto.startPage();
        final List<SynthesisUserRecordVo> page = baseMapper.userSynthesisList(pageDto);
        // 封装消耗/结果相关数据
        wrapperSynthesisUserRecords(page);
        return page;
    }

    /**
     * 封装合成记录相关数据
     *
     * @param records
     */
    private void wrapperSynthesisUserRecords(List<SynthesisUserRecordVo> records) {
        if (CollUtil.isEmpty(records)) {
            return;
        }

        final List<Long> recordIds = records.stream().map(SynthesisUserRecordVo::getId).collect(Collectors.toList());
        final Map<Long, List<SynthesisRecordConsumeResult>> recordMap =
                synthesisRecordConsumeResultMapper.selectList(Wrappers.<SynthesisRecordConsumeResult>lambdaQuery()
                        .in(SynthesisRecordConsumeResult::getRecordId, recordIds)
                        .select(SynthesisRecordConsumeResult::getName,
                                SynthesisRecordConsumeResult::getImgUrl,
                                SynthesisRecordConsumeResult::getRecordType,
                                SynthesisRecordConsumeResult::getOtherNo,
                                SynthesisRecordConsumeResult::getRecordId,
                                SynthesisRecordConsumeResult::getRecordType,
                                SynthesisRecordConsumeResult::getNum
                        )
                ).stream().collect(Collectors.groupingBy(SynthesisRecordConsumeResult::getRecordId));

        for (SynthesisUserRecordVo record : records) {
            final List<SynthesisRecordConsumeResult> tmpRecords = recordMap.get(record.getId());
            List<SynthesisRecordConsumeResult> consumeRecords = new ArrayList<>();
            List<SynthesisRecordConsumeResult> resultRecords = new ArrayList<>();
            for (SynthesisRecordConsumeResult tmpRecord : tmpRecords) {
                if (tmpRecord.getRecordType().equals(SynthesisRecordTypeEnum.CONSUME)) {
                    consumeRecords.add(tmpRecord);
                } else {
                    resultRecords.add(tmpRecord);
                }
            }
            record.setSynthesisConsumeRecords(consumeRecords);
            record.setSynthesisResultRecords(resultRecords);
        }
    }

    /**
     * 获取合成详情
     *
     * @param recordId
     * @return
     */
    public SynthesisUserRecordVo detail(Long recordId, Long userId) {
        final SynthesisUserRecord synthesisUserRecord = baseMapper.selectById(recordId);
        if (synthesisUserRecord == null || !Objects.equals(synthesisUserRecord.getUserId(), userId)) {
            throw new ServiceException("合成记录不存在!");
        }
        SynthesisUserRecordVo recordVo = new SynthesisUserRecordVo();
        BeanUtil.copyProperties(synthesisUserRecord, recordVo);
        wrapperSynthesisUserRecords(Lists.newArrayList(recordVo));
        return recordVo;
    }

    public List<SynthesisUserRecordVo> userWebSynthesisList(SynthesisUserRecordPageDto pageDto) {
        final List<SynthesisUserRecordVo> page = baseMapper.userSynthesisList(pageDto);
        // 封装消耗/结果相关数据
        wrapperSynthesisUserRecords(page);
        return page;
    }

    /**
     * 构建合成记录
     * @return
     */
    public SynthesisUserRecord buildRecord(Long userId, Synthesis synthesis, SynthesisStartDto dto, SynthesisActivityTypeEnum synthesisType){
        SynthesisUserRecord record = new SynthesisUserRecord();
        record.setId(IdUtil.getSnowflakeNextId());
        record.setUserId(userId);
        record.setSynthesisId(synthesis.getId());
        record.setName(synthesis.getName());
        record.setMainImg(synthesis.getMainImg());
        record.setPlanId(synthesis.getPlanId());
        record.setGroupId(dto.getGroupId());
        record.setSynthesisType(synthesisType);
        record.setSynthesisPlanName(dto.getTitle());
        record.setNum(dto.getCount());
        return record;
    }
}
